import { message } from "ant-design-vue"

interface socket {
    webSocket: any
    connectURL: any
    socket_open: boolean
    heartbeat_timer: any
    heartbeat_interval: number
    is_reconnect: boolean
    reconnect_count: number
    reconnect_current: number
    reconnect_number: number
    reconnect_timer: any
    reconnect_interval: number
    init: (connectURL:string, receiveMessage: Function | null) => any
    receive: (message: any) => void
    heartbeat: () => void
    send: (data: any, callback?: any) => void
    close: () => void
    reconnect: () => void
}

const socket: socket = {
    webSocket: null,
    connectURL: null,
    // 开启标识
    socket_open: false,
    // 心跳timer
    heartbeat_timer: null,
    // 心跳发送频率
    heartbeat_interval: 45000,
    // 是否自动重连
    is_reconnect: true,
    // 重连次数
    reconnect_count: 3,
    // 已发起重连次数
    reconnect_current: 1,
    // 网络错误提示次数
    reconnect_number: 0,
    // 重连timer
    reconnect_timer: null,
    // 重连频率
    reconnect_interval: 5000,

    init: (connectURL: string, receiveMessage: Function | null) => {
        socket.connectURL = connectURL
        if(!('WebSocket' in window)) {
            message.warning('浏览器不支持WebSocket')
            return null
        }
        // 已经创建过连接不再重复创建
		// if (socket.websocket) {
		//   return socket.websocket
		// }

        socket.webSocket = new WebSocket(socket.connectURL)
        socket.webSocket.onmessage = (e: any) => {
            if(receiveMessage) {
                receiveMessage(e)
            }
        }

        socket.webSocket.onclose = () => {
            clearInterval(socket.heartbeat_interval)
            socket.socket_open = false

            // 需要重新连接 
            if (socket.is_reconnect) {
                console.log("socket重连中...", socket.reconnect_current)
                socket.reconnect_timer = setTimeout(() => {
                    // 超过重连次数
                    if( socket.reconnect_current > socket.reconnect_count ){
                        clearTimeout(socket.reconnect_timer)
                        socket.is_reconnect = false
                        return
                    }

                    // 记录重连次数
                    socket.reconnect_current++
                    socket.reconnect()
                },socket.reconnect_interval)
            }
        }

        // 连接成功
        socket.webSocket.onopen = function() {
            console.log("socket连接成功!")
            socket.socket_open = true
            socket.is_reconnect = true
            // 开启心跳
            socket.heartbeat()
        }

        // 连接发送错误
        socket.webSocket.onerror = function() {
            console.log("socket连接错误!")
        }

    },

    send: (data:string, callback = null) => {
        // 开启状态直接发送
        if (socket.webSocket.readyState === socket.webSocket.OPEN) {
            
            socket.webSocket.send(JSON.stringify(data))
            if (callback) {
                callback()
            }
            
        // 正在开启状态，则等待1s后重新调用
        }else {
            clearInterval(socket.heartbeat_timer)
            if (socket.reconnect_number < 1) {
                message.error('socket链接已断开')
            }
            socket.reconnect_number++
        }
    },

    receive: (message: any) => {
        const data = JSON.parse(message.data)
		return data
    },

    heartbeat: () => {
        if (socket.heartbeat_timer) {
            clearInterval(socket.heartbeat_timer)
        }

        socket.heartbeat_timer = setInterval(() => {
            let data = {
                content: 'ping'
            }
            var sendData = {
                data: JSON.stringify(data),
            }
            socket.send(sendData)
        }, socket.heartbeat_interval)
    },

    close: () => {
        clearInterval(socket.heartbeat_interval)
        socket.is_reconnect = false
        socket.webSocket.close()
        socket.webSocket = null
        console.log('socke已关闭')
    },

    reconnect: () => {
        if(socket.webSocket && !socket.is_reconnect) {
            socket.close()
        }
        
        socket.init(socket.connectURL, null)
    },
}

export default socket